package cn.hchaojie.camp.javafx.animation;

import javafx.animation.FadeTransition;
import javafx.animation.ParallelTransition;
import javafx.animation.RotateTransition;
import javafx.animation.ScaleTransition;
import javafx.animation.SequentialTransition;
import javafx.animation.Transition;
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.RadioButton;
import javafx.scene.control.Toggle;
import javafx.scene.control.ToggleGroup;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Duration;

public class DemoAnimation extends Application {
	private TranslateTransition translate;
	private RotateTransition rotate;
	private ScaleTransition scale;
	private FadeTransition fade;
	
	private SequentialTransition sequentialTransition;
	private ParallelTransition parallelTransition;

	private ToggleGroup group;
	
	@Override
	public void start(Stage stage) throws Exception {
		Scene scene = new Scene(createContents(), 600, 300);
		
		stage.setScene(scene);
		stage.show();
	}
	
	// 在这里创建页面布局
	private Parent createContents() {
		StackPane stack = new StackPane();
		
		String url = getClass().getResource("mnls.png").toExternalForm();
		ImageView image = new ImageView(url);

		image.setFitHeight(100);
		image.setPreserveRatio(true);

		initTransition(image);
		
		HBox hbox = new HBox(10);
		hbox.setPadding(new Insets(10));
		
		CheckBox cbTranslate = new CheckBox("坐标变换");
		cbTranslate.selectedProperty().addListener((obs, oldValue, newValue) -> {
			handleAnimationChanged(translate, newValue);
		});

		CheckBox cbRotate = new CheckBox("旋转");
		cbRotate.selectedProperty().addListener((obs, oldValue, newValue) -> {
			handleAnimationChanged(rotate, newValue);
		});
		CheckBox cbScale = new CheckBox("缩放");
		cbScale.selectedProperty().addListener((obs, oldValue, newValue) -> {
			handleAnimationChanged(scale, newValue);
		});
		CheckBox cbFade = new CheckBox("淡入淡出");
		cbFade.selectedProperty().addListener((obs, oldValue, newValue) -> {
			handleAnimationChanged(fade, newValue);
		});
		
		Region spacer = new Region();
		spacer.setMaxWidth(Double.MAX_VALUE);
		HBox.setHgrow(spacer, Priority.ALWAYS);
		
		group = new ToggleGroup();
		RadioButton rbSeq = new RadioButton("顺序播放");
		rbSeq.setUserData(sequentialTransition);
		rbSeq.setToggleGroup(group);

		RadioButton rbParallel = new RadioButton("并行播放");
		rbParallel.setToggleGroup(group);
		rbParallel.setUserData(parallelTransition);
		rbParallel.setSelected(true);
		parallelTransition.play();
		
		group.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
			@Override
			public void changed(ObservableValue<? extends Toggle> observable, Toggle oldValue, Toggle newValue) {
				handleToggleChanged(oldValue, newValue);
			}
		});
		hbox.getChildren().addAll(cbTranslate, cbRotate, cbScale, cbFade, spacer, rbSeq, rbParallel);
		
		stack.getChildren().addAll(image, hbox);
		return stack;
	}
	
	private void handleAnimationChanged(Transition animation, Boolean isSelected) {
		if (isSelected) {
			if (!parallelTransition.getChildren().contains(animation)) {
				parallelTransition.getChildren().add(animation);
			}
			
			if (!sequentialTransition.getChildren().contains(animation)) {
				sequentialTransition.getChildren().add(animation);
			}
		} else {
			parallelTransition.getChildren().remove(animation);
			sequentialTransition.getChildren().remove(animation);
		}

		parallelTransition.stop();
		sequentialTransition.stop();
		
		Transition selected = (Transition) group.getSelectedToggle().getUserData();
		selected.playFromStart();
	}
	
	private void handleToggleChanged(Toggle oldValue, Toggle newValue) {
		Transition prev = (Transition) oldValue.getUserData();
		Transition next = (Transition) newValue.getUserData();
		
		prev.stop();
		next.playFromStart();
	}
	
	private void initTransition(ImageView imageView) {
		Duration duration = Duration.millis(1000);
		translate = new TranslateTransition(duration, imageView);
		translate.setFromX(50);
		translate.setToX(150);
		translate.setFromY(50);
		translate.setToY(150);

		rotate = new RotateTransition(duration, imageView);
		rotate.setFromAngle(0);
		rotate.setToAngle(180);

		scale = new ScaleTransition(duration, imageView);
		scale.setFromX(1);
		scale.setToX(1.5);
		scale.setFromY(1);
		scale.setToY(1.5);
		
		fade = new FadeTransition(duration, imageView);
		fade.setFromValue(1);
		fade.setToValue(0.3);
		
		sequentialTransition = new SequentialTransition();
		sequentialTransition.setCycleCount(Transition.INDEFINITE);
		sequentialTransition.setAutoReverse(true);

		parallelTransition = new ParallelTransition();
		parallelTransition.setCycleCount(Transition.INDEFINITE);
		parallelTransition.setAutoReverse(true);
	}

	public static void main(String[] args) {
		launch(args);
	}
}
